import time
from threading import Thread
import threading


class ThreadDemo:
    def work1(self, nums):
        nums.append(44)
        print('---work1---%s' % nums)

    def work2(self, nums):
        print('---work2---%s' % nums)

    def work11(self, num):
        global g_num
        for i in range(num):
            g_num += 1
        print('---work11---, g_num is %d' % g_num)

    def work22(self, num):
        global g_num
        for i in range(num):
            g_num += 1
        print('---work22---, g_num is %d' % g_num)

    def work111(self):
        if self.mutex1.acquire():
            print('----work111---start---')
            time.sleep(1)
            self.mutex1.release()
            if self.mutex2.acquire():
                print('---work111---finish---')
                self.mutex2.release()

    def work222(self):
        if self.mutex2.acquire():
            print('---work222---start---')
            time.sleep(1)
            self.mutex2.release()
            if self.mutex1.acquire():
                print('---work222----finish---')
                self.mutex1.release()

    def work1111(self, num):
        global g_num2
        for i in range(num):
            flag = self.mutex.acquire(True)
            if flag:
                g_num2 += 1
                self.mutex.release()
        print('---work1111---, g_num2 is %d' % g_num2)

    def work2222(self, num):
        global g_num2
        for i in range(num):
            flag = self.mutex.acquire(True)
            if flag:
                g_num2 += 1
                self.mutex.release()
        print('---work2222---, g_num2 is %d' % g_num2)

    def func1(self, num):
        while True:
            time.sleep(2)
            print('study' + str(num))

    def func2(self, num):
        while True:
            time.sleep(2)
            print('sleep' + str(num))

    def saysorry(self):
        print("Sorry!")
        time.sleep(1)

    def _test_array(self):
        """
        td = ThreadDemo()
        td._test_array()
        """
        g_nums = [11, 25, 23]
        t1 = Thread(target=self.work1, args=(g_nums,))
        t1.start()
        t2 = Thread(target=self.work2, args=(g_nums,))
        t2.start()

    def _test_num(self):
        """
        td = ThreadDemo()
        td._test_num()
        """
        t1 = Thread(target=self.work11, args=(10000000,))
        t1.start()
        t2 = Thread(target=self.work22, args=(10000000,))  # 资源竞争导致运算丢失
        t2.start()
        while len(threading.enumerate()) != 1:
            time.sleep(1)
        print('the final num is %d' % g_num)

    def _test_for(self):
        """
        td = ThreadDemo()
        td._test_for()
        """
        for i in range(5):
            t = Thread(target=self.saysorry())
            t.start()

    def _test_deadlock(self):
        """
        td = ThreadDemo()
        td._test_deadlock()
        """
        self.mutex1 = threading.Lock()
        self.mutex2 = threading.Lock()
        t1 = Thread(target=self.work111)
        t2 = Thread(target=self.work222)  # 时间不满足导致死锁
        t1.start()
        t2.start()

    def _test_mutex(self):
        """
        td = ThreadDemo()
        td._test_mutex()
        """
        self.mutex = threading.Lock()
        t1 = threading.Thread(target=self.work1111, args=(10000000,))
        t1.start()
        t2 = threading.Thread(target=self.work2222, args=(10000000,))  # 互斥锁解决资源竞争问题
        t2.start()
        while len(threading.enumerate()) != 1:
            time.sleep(1)
        print('the final num is %d' % g_num)

    def _test_thread_multi(self):
        """
        td = ThreadDemo()
        td._test_thread_multi()
        """
        t_list = []
        for i in range(5):
            t1 = Thread(target=self.func1, args=(i,))
            t_list.append(t1)
        for i in range(5):
            t2 = Thread(target=self.func2, args=(i,))
            t_list.append(t2)
        for t in t_list:
            t.start()


class ThreadOverrideDemo(Thread):
    def run(self):
        print("Sorry!")
        time.sleep(1)

    def _test_override(self):
        """
        tod = ThreadOverrideDemo()
        tod._test_override()
        """
        for i in range(5):
            tod = ThreadOverrideDemo()
            tod.start()


g_num = g_num2 = 0

if __name__ == '__main__':
    td = ThreadDemo()
    td._test_thread_multi()
